<script setup>
import {
  onMounted,
  toRefs,
  nextTick,
  watch,
  ref,
  getCurrentInstance,
  inject,
  computed
} from 'vue'
import { addTokenToUrl } from '../../../utils/token'
import { uploadImg } from '../../../service/api'
import {
  jumpHttp,
  isIos,
  getAllSrc,
  isMobile,
  isWeixinMini
} from '../../../utils/host'
import botDefault from '../../../assets/img/school.png'
// echarts 折线图
import * as echarts from 'echarts/core'
import {
  TitleComponent,
  ToolboxComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent
} from 'echarts/components'
import { LineChart, PieChart, BarChart } from 'echarts/charts'
import { UniversalTransition } from 'echarts/features'
import { CanvasRenderer } from 'echarts/renderers'
import { useAudioStore } from '../../../stores/audio'

import Card from './Card.vue'
import FileItem from './FileItem.vue'

import playImg from '../../../assets/img/play.png'
import pauseImg from '../../../assets/img/pause.png'
import appDefault from '../../../assets/img/appdef.png'
echarts.use([
  TitleComponent,
  ToolboxComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  LineChart,
  PieChart,
  BarChart,
  CanvasRenderer,
  UniversalTransition
])
const { appContext } = getCurrentInstance()
const proxy = appContext.config.globalProperties
const config = proxy.$config
const chartDom1 = ref()
const chartDom2 = ref()
const chartDom3 = ref()

const option1 = {
  title: {
    text: ''
  },
  tooltip: {
    trigger: 'item'
  },
  legend: {},
  grid: {
    left: '12px',
    right: '12px',
    bottom: '22px',
    top: '22px',
    containLabel: true
  },
  yAxis: {
    type: 'value'
  },
  xAxis: {
    type: 'category',
    axisLabel: {
      // 按每三个字换行
      color: '#333',
      fontSize: 12,
      lineHeight: 16,
      formatter: function (value) {
        // 如果文本超过8个字，则显示前三个字加省略号
        // 每四个字换行
        let newValue = ''
        for (let i = 0; i < value.length; i += 4) {
          newValue += value.slice(i, i + 4) + '\n'
        }
        let tempValue = newValue.trim()
        if (tempValue.length > 8) {
          tempValue = tempValue.slice(0, 8) + '...'
        }

        return tempValue // 去除最后的换行符
      },
      // 如果想要换行间隔，可以设置 interval: 0
      interval: 0
    },

    data: []
  },
  series: []
}
const option2 = {
  tooltip: {
    trigger: 'item'
  },
  legend: {
    left: 'right',
    right: 12,
    top: 8,
    itemWidth: 16, // 控制图例前面图形的宽度
    itemHeight: 8, // 控制图例前面图形的高度
    color: ['#76B2FF'],
    data: []
  },
  grid: {
    left: '12px',
    right: '12px',
    bottom: '12px',
    top: '12px',
    containLabel: true
  },
  xAxis: {
    type: 'category',
    axisTick: {
      show: false // 隐藏 刻度线
    },
    axisLine: {
      show: true, // 显示 轴线
      lineStyle: {
        color: 'rgba(216,214,214,0.5)', // 设置轴线颜色
        width: 2, // 设置轴线宽度
        type: 'solid' // 设置轴线类型
      }
    },
    axisLabel: {
      // 按每三个字换行
      color: '#131415;',
      fontSize: 12,
      lineHeight: 16,
      formatter: function (value) {
        let newValue = ''
        for (let i = 0; i < value.length; i += 10) {
          newValue += value.slice(i, i + 10) + '\n'
        }
        let tempValue = newValue.trim()
        if (tempValue.length > 20) {
          tempValue = tempValue.slice(0, 20) + '...'
        }

        return tempValue // 去除最后的换行符
      },
      // 如果想要换行间隔，可以设置 interval: 0
      interval: 0
    },
    data: []
    // boundaryGap: false,
  },
  yAxis: {
    type: 'value',
    // 数据不支持
    // name: '得分',
    // nameLocation: 'end', // 单位显示在轴的末端
    // nameTextStyle: {
    //   fontSize: 12,
    //   color: '#333',
    //   padding: [0, 0, -65, 50] // 调整单位的位置
    // },
    // nameGap: 50, // 单位和轴线之间的距离
    axisLine: {
      show: true, // 显示 Y 轴线
      symbol: ['none', 'arrow'], // 为 Y 轴添加箭头
      symbolSize: [5, 10], // 设置箭头的大小
      lineStyle: {
        color: 'rgba(216,214,214,0.5)', // 设置轴线颜色
        width: 1, // 设置轴线宽度
        type: 'solid' // 设置轴线类型
      }
    },
    axisLabel: {
      show: false // 隐藏数值标签
    },
    splitLine: {
      show: true, // 显示刻度线
      lineStyle: {
        type: 'dashed', // 设置虚线
        color: 'rgba(216,214,214,0.6)', // 设置虚线颜色
        width: 1 // 设置虚线宽度
      }
    },
    // 设置Y轴的范围
    max: 120 // 根据数据情况调整最大值
  },
  series: []
}
const agentConfig = inject('agentConfig')
const props = defineProps({
  type: {
    type: String, // User(发送的问题) || Bot(答案) || Kefu(人工客服) || PreAbnormal(前置异常) || "XYWD": 校园问答 || "ZDWX": 制度问询 || "ZNWS": 智能问数 || "YYDH": 应用导航
    default: 'Text'
  },
  stype: {
    type: Number,
    default: 0
  },
  i: {
    type: Number,
    default: 0
  }, // 消息索引
  name: {
    type: String,
    default: ''
  },
  answer: {
    type: String,
    default: ''
  },
  description: {
    type: String,
    default: ''
  },
  processInfo: {
    type: String,
    default: ''
  },
  message: {
    type: String,
    default: ''
  },
  thinking: {
    type: String,
    default: ''
  },
  resources: {
    type: Array,
    default: () => {
      return []
    }
  },
  isLoading: {
    type: Boolean,
    default: false
  },
  toolLoading: {
    type: Boolean,
    default: false
  },
  showInfo: {
    type: Boolean,
    default: false
  },
  quote: {
    type: Array,
    default: () => {
      return []
    }
  },
  isTextEnd: {
    type: Boolean,
    default: false
  },
  isActive: {
    type: Boolean
  },
  isAnswering: {
    type: Boolean
  },
  uuid: {
    type: String,
    default: ''
  },
  needUploadImg: {
    type: Boolean
  },
  list: {
    type: Array,
    default: () => {
      return []
    }
  },
  extraData: {
    type: Object,
    default: () => {
      return {
        type: '',
        data: {}
      }
    }
  },
  btns: {
    type: Array,
    default: () => {
      return []
    }
  },
  hrefList: {
    type: Array,
    default: () => {
      return []
    }
  },
  opsStatus: {
    type: String,
    default: '0'
  },
  chatType: {
    type: String,
    default: ''
  },
  src: {
    type: String,
    default: ''
  },
  muted: {
    type: Boolean
  },
  isError: {
    type: Boolean,
    default: false
  },
  actionType: {
    type: String,
    default: 'normal'
  },
  isHistory: {
    type: Boolean
  },
  total: {
    type: Number,
    default: 0
  }
})

const emits = defineEmits([
  'emitSend',
  'emitScroll',
  'refresh',
  'emitKefu',
  'emitRef',
  'emitImg',
  'stopAi',
  'emitEvalute',
  'emitStatus',
  'emitPlay',
  'emitPause',
  'emitEnd',
  'emitDoc'
])

const {
  i,
  name,
  type,
  stype,
  answer,
  description,
  processInfo,
  message,
  isLoading,
  toolLoading,
  showInfo,
  quote,
  thinking,
  resources,
  isActive,
  isAnswering,
  uuid,
  needUploadImg,
  list,
  extraData,
  btns,
  hrefList,
  opsStatus,
  chatType,
  src,
  muted,
  isError,
  actionType,
  isHistory
} = toRefs(props)
// 是否为最后一条message
const isLast = computed(() => props.i === props.total - 1)
// 引用切片里面的图片
const imgs = ref([])

const go = (item) => {
  if (!item.link) {
    proxy.$toast('当前服务正在和学校建设中，请耐心等待吧')
    return
  }
  if (item.type === 4) {
    // 跳转app应用 wanxiao://......
    if (!isMobile()) {
      proxy.$toast('请在移动端使用此功能')
      return
    }
    window.location.href = item.link
  } else if (item.type === 2) {
    if (!isWeixinMini()) {
      proxy.$toast('请在微信小程序环境使用此功能')
      return
    }
    wx.miniProgram.navigateTo({
      url: item.link
    })
  } else if (item.type === 3) {
    // 跳转http链接
    item.link = !isMobile() ? item.pcLink : item.link
    const url =
      item.appendToken === 1
        ? addTokenToUrl(
            item.link,
            item.putTokenName || 'token',
            item.gainTokenName || 'token'
          )
        : item.link
    if (url === 'invalid url') {
      proxy.$toast('地址解析失败，请检查配置')
      return
    }
    jumpHttp(url)
  }
}
const isExpanded = ref(false)
// 展开收起
const toggleExpand = () => {
  isExpanded.value = !isExpanded.value
}
// 处理表格图形数据及样式展开折叠逻辑
// 控制显示的内容条数
const tableTr = computed(() => {
  return isExpanded.value
    ? extraData.value?.data?.tr
    : extraData.value?.data?.tr?.slice(0, 7)
})

const hasInitChart = ref(false)

// 处理柱状图的数据及样式展开折叠逻辑
// 控制显示的柱状图内容条数
const barChartXAxis = computed(() => {
  return extraData.value?.data?.xAxis
})
const barChartseries = computed(() => {
  return extraData.value?.data?.series
})
const barChartWidth = computed(() => {
  let width = 0
  width = extraData.value?.data?.xAxis?.length * 1.8 + 'rem'
  return extraData.value?.data?.xAxis?.length <= 3 ? '5.56rem' : width
})

// 设置柱状图
const setBar = () => {
  if (hasInitChart.value) return
  option1.xAxis.data = barChartXAxis.value
  option1.series = barChartseries.value
  nextTick(() => {
    if (chartDom1.value) {
      const myChart = echarts.init(chartDom1.value)
      myChart.setOption(option1)
      // 调整图表大小
      myChart.resize()
      hasInitChart.value = true
    }
  })
}

const lineChartWidth = computed(() => {
  let width = 0
  width = extraData.value?.data?.xAxis?.length * 1.8 + 'rem'
  return extraData.value?.data?.xAxis?.length <= 3 ? '5.56rem' : width
})

// 设置折线图
const setLine = () => {
  if (hasInitChart.value) return
  option2.xAxis.data = extraData.value?.data?.xAxis
  option2.series = extraData.value?.data?.series
  // option2.series.name = extraData.value?.data?.name
  // option2.legend.data[0] = extraData.value?.data?.name
  nextTick(() => {
    if (chartDom2.value) {
      const myChart = echarts.init(chartDom2.value)
      myChart.setOption(option2)
      // 调整图表大小
      myChart.resize()
      hasInitChart.value = true
    }
  })
}

// 设置饼图
const setPie = () => {
  if (hasInitChart.value) return
  const data = extraData.value?.data?.series || []
  const total = data.reduce((sum, item) => sum + item.value, 0)
  const option3 = {
    tooltip: {
      trigger: 'item',
      formatter: function (params) {
        return `${params.value}`
      }
    },
    legend: {
      type: 'scroll',
      orient: 'horizontal',
      top: '5%',
      left: 'center',
      data: data.map((item) => item.name)
    },
    series: [
      {
        type: 'pie',
        radius: ['40%', '70%'],
        center: ['50%', '55%'],
        avoidLabelOverlap: false,
        label: {
          show: false,
          position: 'center'
        },
        emphasis: {
          label: {
            show: true,
            fontSize: 20,
            fontWeight: 'bold'
          }
        },
        labelLine: {
          show: false
        },
        data
      }
    ]
  }
  nextTick(() => {
    if (chartDom3.value) {
      const myChart = echarts.init(chartDom3.value)
      myChart.setOption(option3)
      hasInitChart.value = true
    }
  })
}
// 监听extraData变化 处理图表的数据
watch(
  extraData,
  (newValue, oldValue) => {
    if (extraData.value?.type === 'bar') {
      setBar()
    } else if (extraData.value?.type === 'line') {
      setLine()
    } else if (extraData.value?.type === 'pie') {
      setPie()
    }
  },
  { deep: true, immediate: true }
)

const stopAi = () => {
  emits('stopAi', true)
}
// 数据来源
// 定义map
const sourceMap = new Map([
  [1, '以上内容由AI生成，仅供参考'],
  [4, '以上信息由AI大模型依据校园公开资讯生成，内容仅供参考'],
  [12, '以上信息由AI大模型依据公开资讯生成，仅供参考'],
  [
    5,
    '以上信息来自官方回答，由AI大模型依据校内知识库-常见问题生成，内容仅供参考'
  ],
  [51, '以上信息来自官方回答，由AI大模型依据校内知识库-文档生成，内容仅供参考'],
  [
    8,
    '以上信息来源于校园各业务系统，数据可能存在延时，本查询结果仅供参考，如有疑问，请联系各相关部门咨询或者通过本页面人工客服入口反馈。'
  ]
])

const sourceText = computed(() => {
  return sourceMap.get(stype.value)
})
// 是否解决
const solve = (status) => {
  if (status === opsStatus.value) return
  emits('emitEvalute', {
    question: answer.value,
    ask: name.value,
    index: i.value,
    uuid: uuid.value,
    status,
    chatType: chatType.value
  })
}

watch(type, () => {
  nextTick(() => {
    emits('emitScroll')
  })
})

watch(quote, (v) => {
  if (v) {
    v.forEach((item) => {
      // item.ref_content = `<p>${item.ref_content}</p>`
      imgs.value = imgs.value.concat(getAllSrc(item.ref_content))
    })
    imgs.value.forEach((src) => {
      const img = new Image()
      img.src = src
      img.onload = () => {
        emits('emitScroll')
      }
    })
  }
})

watch(src, (v) => {
  if (v) {
    setTimeout(() => {
      voice.value.addEventListener('ended', () => {
        isPlay.value = false
        emits('emitEnd')
      })
    }, 50)
  }
})

// 点击查看文档引用
const showRef = (item) => {
  emits(
    'emitRef',
    item.ref_content
      .replace(/--------------------/g, '\n')
      .replace(/知识点：\n/g, '')
  )
}

// 人工客服
const kefu = () => {
  setTimeout(() => {
    const url = config.manServiceToken
      ? addTokenToUrl(config.manServiceUrl, 'token', 'token')
      : config.manServiceUrl
    if (url === 'invalid url') {
      proxy.$toast('地址解析失败，请检查配置')
      return
    }
    jumpHttp(url)
  }, 50)
}

// 富文本转成文本，去掉html标签
const getSimpleText = (html) => {
  const re1 = new RegExp('<.+?>', 'g') // 匹配html标签的正则表达式，"g"是搜索匹配多个符合的内容
  const arrEntities = {
    lt: '<',
    gt: '>',
    nbsp: ' ',
    amp: '&',
    quot: '"',
    ldquo: '“',
    mdash: '—',
    rdquo: '”'
  }
  return html
    .replace(re1, '')
    .replace(/&(lt|gt|nbsp|amp|quot|ldquo|mdash|rdquo);/gi, function (all, t) {
      return arrEntities[t]
    })
}

const copy = () => {
  const textArea = document.createElement('textArea')
  textArea.value = getSimpleText(message.value)
  textArea.style.width = 0
  textArea.style.position = 'fixed'
  textArea.style.left = '-999px'
  textArea.style.top = '10px'
  textArea.setAttribute('readonly', 'readonly')
  document.body.appendChild(textArea)

  textArea.select()
  document.execCommand('copy')
  document.body.removeChild(textArea)

  proxy.$toast('已复制')
}

// 点击消息里面的按钮（多轮对话）
const handleClick = (name) => {
  emits('emitSend', {
    data: {
      name
    }
  })
}

// 点击智能体发送消息
const sendFromAgentList = (name) => {
  handleClick(name)
}

const chooseDoc = (e) => {
  emits('emitDoc', e)
}

// show funs 推荐应用
const showFunc = ref(true)
const toggleFuns = () => {
  showFunc.value = !showFunc.value
}

// 上传图片
const showAddBtn = ref(true)
const upload = ref()
const uploadImgArr = ref([])
let uploadImgs = ''
const imageChange = () => {
  const l = upload.value.files.length
  proxy.$toast.loading({
    message: '上传中...',
    duration: 0,
    forbidClick: true
  })
  for (let i = 0; i < l; i++) {
    const file = upload.value.files[i]
    uploadImg({
      file
    }).then((res) => {
      showAddBtn.value = false
      uploadImgArr.value.push(res.link)
      if (uploadImgArr.value.length === l) {
        proxy.$toast.clear()
        uploadImgs = uploadImgArr.value.join(',')
        // 3: 发送用户上传图片
        setTimeout(() => {
          emits('emitSend', {
            type: 3,
            data: {
              name: `图片列表: ${uploadImgs}`
            }
          })
        }, 1000)
      }
    })
  }
}

// a标签跳转、img预览   stype = 7 stype = 5
const jumpA = (e) => {
  e.preventDefault()
  if (stype.value === 7) {
    if (e.target.nodeName === 'A') {
      const index = e.target.getAttribute('href')
      if (index) {
        window.location.href = hrefList.value[index]
      }
    }
  }

  if (stype.value === 5) {
    if (e.target.nodeName === 'A') {
      const url = e.target.getAttribute('href')
      jumpHttp(url)
    }
  }
  if (e.target.nodeName === 'IMG') {
    const src = e.target.getAttribute('src')
    if (src) {
      emits('emitImg', {
        imgs: [src],
        index: 0
      })
    }
  }
}

const voice = ref()
const isPlay = ref(false)
const audioStore = useAudioStore()
const playAnswer = () => {
  audioStore.setPlaying(props.i)
  if (voice.value.paused) {
    voice.value.play()
    emits('emitPlay', actionType.value)
    isPlay.value = true
  } else {
    voice.value.pause()
    emits('emitPause')
    isPlay.value = false
  }
}

onMounted(() => {
  document.addEventListener('forcePause', (e) => {
    if (!voice.value) {
      return
    }
    if (e.detail.except !== props.i) {
      voice.value.pause()
      emits('emitPause')
      isPlay.value = false
    }
  })
})
</script>

<template>
  <div class="mw">
    <div class="message-wrap bot" v-if="type === 'Bot'">
      <audio v-show="isIos() && src" ref="voice" :src="src" :muted="muted" />
      <div class="AI" v-if="isLoading">
        <img class="avatar" :src="agentConfig.icon || botDefault" />
        <div class="loadwrap">
          <span>AI思考中</span>
          <div class="loader">
            <div class="box-load1" />
            <div class="box-load2" />
            <div class="box-load3" />
          </div>
        </div>
      </div>
      <div class="message" v-show="message || stype === 8 || thinking">
        <div class="process-wrap" v-if="processInfo && !isTextEnd">
          <div id="loading">
            <div />
            <div />
            <div />
          </div>
          <span class="info">{{ processInfo }}</span>
        </div>

        <div class="thinking" v-if="thinking">
          <div class="thinking-text">思考中...</div>
          <span class="rich-text" v-html="thinking" />
        </div>
        <div class="AI" v-if="toolLoading && isAnswering">
          <div class="loadwrap">
            <span>工具运行中</span>
            <div class="loader">
              <div class="box-load1" />
              <div class="box-load2" />
              <div class="box-load3" />
            </div>
          </div>
        </div>
        <!-- <div class="thinking" v-if="toolLoading">
          <div class="tooling-text"> <van-loading type="spinner" />正在使用工具...</div>
        </div> -->
        <!-- <span class="rich-text">{{ message }}<span v-if="!showInfo" class="flashing-line" /></span> -->
        <span
          v-if="stype == 7 || stype == 5 || stype == 4"
          class="rich-text"
          v-html="message"
          @click="jumpA($event)"
        />
        <span v-else class="rich-text" v-html="message" />

        <div v-if="btns.length && showInfo" class="btns">
          <div
            class="btn oneline"
            v-for="(item, index) in btns"
            :key="index"
            @click="handleClick(item)"
          >
            {{ item }}
            <span class="next" />
          </div>
        </div>
        <section style="position: relative">
          <div
            class="table-content table"
            v-if="extraData?.type === 'table' && showInfo"
          >
            <table>
              <thead>
                <tr v-if="extraData?.data?.th?.length">
                  <th v-for="(item, index) in extraData?.data?.th" :key="index">
                    {{ item }}
                  </th>
                </tr>
              </thead>
              <tbody>
                <tr v-for="(l, c) in tableTr" :key="c">
                  <td v-for="(m, n) in l" :key="n">
                    {{ m }}
                  </td>
                </tr>
                <!-- 展开/收起按钮 -->
                <tr
                  @click="toggleExpand"
                  v-if="extraData?.data?.tr?.length > 7"
                >
                  <td :colspan="extraData?.data?.th?.length">
                    <div class="toggle-expand-tr" />
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
          <div
            class="toggle-expand"
            @click="toggleExpand"
            v-if="extraData?.data?.tr?.length > 7 && showInfo"
          >
            {{ isExpanded ? '收起' : '展开' }}
          </div>
          <div
            class="bar-chart-wrap"
            v-show="extraData?.type === 'bar' && showInfo"
          >
            <div
              class="chart"
              ref="chartDom1"
              :style="{ width: barChartWidth }"
            />
            <div
              class="toggle-expand"
              @click="toggleExpandChart"
              v-if="extraData?.data?.yAxis?.length > 5 && showInfo"
            >
              {{ isExpanded ? '收起' : '展开' }}
            </div>
          </div>
          <div
            class="line-chart-wrap"
            v-show="extraData.type === 'line' && showInfo"
          >
            <div
              class="chart"
              ref="chartDom2"
              :style="{ width: lineChartWidth }"
            />
          </div>
          <div
            class="pie-chart-wrap"
            v-show="extraData.type === 'pie' && showInfo"
          >
            <div class="chart" ref="chartDom3" />
          </div>
          <div class="text-wrap" v-show="extraData.type === 'text' && showInfo">
            <span class="rich-text description">{{
              extraData?.data?.text
            }}</span>
          </div>
        </section>
        <div />
        <div v-if="resources.length && showInfo" class="source">
          <div class="source-title">引用</div>
          <div class="source-content">
            <div v-for="(item, index) in resources" :key="index">
              <FileItem :fitem="item" />
            </div>
          </div>
        </div>
        <span v-if="description && showInfo" class="rich-text description"
          >数据说明：{{ description }}</span
        >

        <div class="quote" v-if="quote.length && showInfo">
          <div class="refs">
            <span class="t">找到了以下{{ quote.length }}篇资料作为参考</span>
            <span
              v-for="(item, index) in quote"
              :key="index"
              @click="showRef(item)"
              >{{ item.ref_name }}</span
            >
          </div>
        </div>

        <div class="upload">
          <div class="list" v-if="uploadImgArr.length">
            <img
              v-for="(item, index) in uploadImgArr"
              :key="index"
              class="img"
              :src="item"
            />
          </div>
          <div class="wrap" v-if="needUploadImg && showAddBtn">
            <input
              ref="upload"
              type="file"
              multiple
              accept="image/*"
              @change="imageChange"
            />
          </div>
        </div>
        <div class="tips" v-if="showInfo">
          {{ sourceText }}
        </div>
        <div v-if="list.length && showInfo" class="funcs">
          <div class="suggest">
            <span class="airec" />
            <span>相关应用 · {{ list.length }}</span>
            <span
              class="toggle"
              :class="{ up: showFunc, down: !showFunc }"
              @click="toggleFuns"
            />
          </div>
          <Transition>
            <div ref="funcRef" class="funcs-wrap" v-if="showFunc">
              <div
                class="func"
                v-for="(item, index) in list"
                :key="index"
                @click="go(item)"
              >
                <img :src="item.icon || appDefault" />
                <span class="title oneline">{{ item.name }}</span>
              </div>
            </div>
          </Transition>
        </div>

        <div class="bottom">
          <div
            v-if="showInfo && isIos() && !isError && src && !isHistory"
            class="MP3_btn"
            @click="playAnswer"
          >
            <div>
              <img :src="isPlay ? pauseImg : playImg" />
              <span>{{ isPlay ? '暂停' : '播放' }}</span>
            </div>
          </div>
          <div class="ops">
            <div
              @click="stopAi"
              style="margin-right: 0.24rem"
              v-if="isActive && isAnswering && !isHistory"
            >
              停止
            </div>
            <div v-if="showInfo" @click="copy" style="margin-right: 0.24rem">
              <img src="../../../assets/img/copy.png" />
              <span>复制</span>
            </div>
            <div
              @click="solve('1')"
              v-if="isLast"
              style="margin-right: 0.24rem"
            >
              <img
                v-if="opsStatus === '0' || opsStatus === '2'"
                src="../../../assets/img/good2.png"
              />
              <img
                class="like"
                v-if="opsStatus === '1'"
                src="../../../assets/img/good1.png"
              />
              <span :class="{ active: opsStatus === '1' }">点赞</span>
            </div>
            <div
              @click="solve('2')"
              v-if="isLast"
              style="margin-right: 0.28rem"
            >
              <img
                v-if="opsStatus === '0' || opsStatus === '1'"
                src="../../../assets/img/nogood2.png"
              />
              <img
                class="unlike"
                v-if="opsStatus === '2'"
                src="../../../assets/img/nogood1.png"
              />
              <span :class="{ active: opsStatus === '2' }">踩</span>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="message-wrap user" v-if="type === 'User'">
      <div class="message" @click="copy">
        <span class="rich-text" v-html="message" />
      </div>
    </div>
    <div class="message-wrap preabnormal" v-if="type === 'PreAbnormal'">
      <div class="message">
        <div class="ops">
          <span class="tip" />
        </div>
        {{ message }}
      </div>
    </div>
    <div class="message-wrap kefu" v-if="type === 'Kefu'" @click="kefu">
      <span>问题未解决，我要转</span><span class="active">人工客服</span>
    </div>
    <template v-if="type === 'ZNT'">
      <Card card-type="1" @emit-send="sendFromAgentList" />
    </template>
    <div class="s-title" v-if="type === 'Stitle'">
      {{ message }}
    </div>
  </div>
</template>

<style lang="less">
/* 设置表格的基本样式 */
.table-style() {
  table {
    min-width: 100%;
    border-collapse: collapse; /* 边框合并 */
    font-size: 0.24rem;
    // border-radius: 5px 5px 0 0; /* 圆角边框 */
    // overflow: hidden;
    // box-shadow: 0 0 20px rgba(0, 0, 0, 0.15); /* 阴影效果 */
  }
  /* 设置表头的样式 */
  th {
    color: #333;
    padding: 0.13rem 0.24rem;
    text-align: left;
    border: none;
    font-weight: normal;
    white-space: nowrap;
    background: #e0e2eb;
  }
  tr {
    border: none;
    background-color: #f7f8fa;
  }
  tr:nth-child(odd) {
    background-color: #f1f2f6;
  }
  td {
    color: #333;
    padding: 0.05rem 0.24rem;
    border: none;
    text-align: left;
    white-space: nowrap;
  }
  th:first-child,
  td:first-child {
    padding-left: 0.38rem; /* 第一列左边距 */
  }
  th:last-child,
  td:last-child {
    padding-right: 0.38rem; /* 最后一列右边距 */
  }
}
.mw {
  margin-bottom: 0.24rem;
}
.message-wrap {
  display: flex;
  .active {
    color: #f59f49;
  }
  .message {
    background-color: #fefefe;
    border-radius: 0.16rem;
    max-width: 100%;
    font-size: 0.24rem;
    color: #333;
    word-wrap: break-word;
    // white-space: pre-wrap;
    line-height: 0.4rem;
    .toolHtml {
      background-color: #eef8ff;
      border-radius: 0.16rem;
      padding: 0.14rem;
      font-size: 0.24rem;
      margin: 0.1rem 0;
      padding-left: 0.56rem;
      background-image: url('../../../assets/img/tool.png');
      background-size: 0.28rem 0.28rem;
      background-repeat: no-repeat;
      background-position: 0.16rem 0.2rem;
      vertical-align: middle;
    }
  }
  .process-wrap {
    display: flex;
    font-size: 0.24rem;
    padding: 0.16rem;
    background: #f1f2f6;
    border-radius: 0.16rem;
    #loading,
    #loading > div {
      position: relative;
      box-sizing: border-box;
    }

    #loading {
      display: block;
      font-size: 0;
      color: #000;
    }

    #loading.la-dark {
      color: #333;
    }

    #loading > div {
      display: inline-block;
      float: none;
      background-color: currentColor;
      border: 0 solid currentColor;
    }

    #loading {
      width: 0.2rem;
      height: 0.2rem;
    }

    #loading > div {
      position: absolute;
      top: 0;
      left: 0;
      width: 0.1rem;
      height: 0.1rem;
      border-radius: 100%;
    }

    #loading > div:nth-child(1) {
      animation: ball-triangle-path-ball-one 2s 0s ease-in-out infinite;
    }

    #loading > div:nth-child(2) {
      animation: ball-triangle-path-ball-two 2s 0s ease-in-out infinite;
    }

    #loading > div:nth-child(3) {
      animation: ball-triangle-path-ball-tree 2s 0s ease-in-out infinite;
    }
    .info {
      margin-left: 0.2rem;
    }
  }
  .rich-text {
    width: 100%;
    display: inline-block;
    word-break: break-all;
    font-size: 0.28rem;
    width: 100%;
    display: inline-block;
    word-break: break-all;
    font-size: 0.28rem;
    overflow-x: auto;
    .table-style();
    table {
      max-width: 100%;
      width: auto !important; /* 覆盖内联样式 */
      display: block;
      overflow-x: auto;
      white-space: nowrap; /* 保持表格不换行 */
    }
    video {
      max-width: 100%;
      height: auto;
      display: block;
    }
    /* 隐藏全屏按钮（不一定在所有浏览器都有效） */
    video::-webkit-media-controls-fullscreen-button {
      display: none;
    }

    video::-moz-media-controls-fullscreen-button {
      display: none;
    }

    video::-ms-fullscreen-button {
      display: none;
    }
    // 防止字体过大
    h1 {
      font-size: 0.28rem !important;
    }
    h2 {
      font-size: 0.28rem !important;
    }
    pre {
      overflow: auto;
      &::-webkit-scrollbar {
        width: 4px;
        height: 4px;
      }
    }
    img {
      max-width: 100%;
    }
  }
  .source {
    .source-title {
      background-color: #f4f5f7;
      color: #333333;
      margin-bottom: 0.1rem;
      font-size: 0.24rem;
      margin-top: 0.24rem;
      padding: 0.08rem 0.16rem;
      position: relative;
      // &::after {
      //   content: '';
      //   display: inline-block;
      //   width: calc(100% - 0.6rem);
      //   height: 1px;
      //   position: absolute;
      //   bottom: 50%;
      //   background-color: #000;
      // }
    }
    .source-content {
      padding: 0 0.16rem;
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      align-items: center;
      overflow-x: auto;
    }
  }
  .description {
    width: 100%;
    display: inline-block;
    word-break: break-all;
    font-size: 0.24rem;
    padding: 0.16rem;
    background: #f1f2f6;
    border-radius: 0.16rem;
    line-height: 0.36rem;
    margin: 0.18rem auto 0 auto;
  }
  .item {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    // border-bottom: 0.5px solid #eeeeee;
    padding-right: 0.12rem;
    .content {
      width: 100%;
      padding: 0.2rem 0.06rem;
      position: relative;
    }
    .next {
      width: 0.12rem;
      height: 0.26rem;
      background-image: url('../../../assets/img/next.png');
      background-size: 100% 100%;
    }
  }
  .flashing-line {
    display: inline-block;
    width: 2px;
    height: 0.3rem;
    background-color: #000;
    // animation: blink 1s infinite;
    position: relative;
    top: 0.06rem;
  }
  .item:last-child.van-hairline--bottom:after {
    border: none;
  }
  .avatar {
    width: 0.48rem;
    height: 0.48rem;
    border-radius: 50%;
  }
}

.kefu {
  justify-content: center;
  color: #333;
  font-size: 0.28rem;
  border-radius: 0.16rem;
  background-color: white;
  padding: 0.16rem 0.24rem;
  margin: 0 auto;
  margin-bottom: 0.24rem;
}

.preabnormal {
  text-indent: 0;
  .message {
    padding: 0.16rem;
  }
  .ops {
    display: flex;
    flex-direction: row;
    align-items: center;
    color: #f59f49;
    font-size: 0.24rem;
    .tip {
      width: 1.66rem;
      height: 0.42rem;
      background-image: url('../../../assets/img/preabnormal.png');
      background-size: 100% 100%;
    }
    .change {
      position: relative;
      color: #5496f2;
      margin-left: 0.84rem;
      &:before {
        position: absolute;
        content: '';
        width: 0.26rem;
        height: 0.3rem;
        background-image: url('../../../assets/img/refresh1.png');
        background-size: 100% 100%;
        left: -0.36rem;
        top: 0.02rem;
      }
    }
  }
}

.user {
  flex-direction: row-reverse;
  .message {
    background: linear-gradient(90deg, #6ab8ff 0%, #54afff 100%);
    border-radius: 0.32rem 0.32rem 0px 0.32rem;
    padding: 0.16rem 0.2rem;
    color: #fafcfe;
    .rich-text {
      font-size: 0.3rem;
      line-height: 0.4rem;
      vertical-align: middle;
    }
  }
}

.bot {
  flex-direction: column;
  audio {
    width: 0;
    height: 0;
    opacity: 0;
  }
  .AI {
    display: flex;
    flex-direction: row;
    align-items: center;
    font-size: 0.28rem;
    color: #333;
    width: 3rem;
    height: 0.64rem;
    background: #f7faff;
    border-radius: 0.32rem 0.32rem 0.32rem 0;
    padding-left: 0.1rem;
    span {
      margin-left: 0.1rem;
    }
    .loadwrap {
      display: flex;
      .loader {
        display: flex;
        transition: all 0.4s;
        align-items: center;
      }
      .loader div {
        margin-left: 0.08rem;
        background-color: #b6d9f2;
        border-radius: 100%;
        height: 0.1rem;
        width: 0.1rem;
      }
      .box-load1 {
        animation: brighten 1.2s infinite;
      }
      .box-load2 {
        animation: brighten 1.2s infinite;
        animation-delay: 0.3s;
      }
      .box-load3 {
        animation: brighten 1.2s infinite;
        animation-delay: 0.6s;
      }
    }
  }
  .message {
    padding: 0.16rem;
    width: 5.88rem;
    .thinking {
      width: 100%;
      background-color: #f1f2f6;
      border-radius: 0.16rem;
      padding: 0.16rem;
      display: inline-block;
      word-break: break-all;
      pre {
        overflow: auto;
      }
      .thinking-text {
        font-size: 0.24rem;
        color: #999;
        margin-bottom: 0.16rem;
      }
      .tooling-text {
        font-size: 0.24rem;
        color: #999;
      }
    }
    .tips {
      // color: #999;
      font-size: 0.24rem;
      margin-top: 0.2rem;
    }
    .quote {
      color: #999;
      font-size: 0.24rem;
      margin-top: 0.24rem;
      .imgs {
        padding: 0.24rem 0;
        display: flex;
        align-items: center;
        justify-content: flex-start;
        flex-wrap: wrap;
        img {
          width: 1.72rem;
          height: 1.72rem;
          margin-right: 0.13rem;
          margin-bottom: 0.13rem;
        }
      }
      .refs {
        display: flex;
        flex-direction: column;
        .t {
          background-color: #f4f5f7;
          color: #333333;
          margin-bottom: 0.2rem;
        }
        span {
          line-height: 1.4;
          color: #1989fa;
          padding: 0.08rem 0.16rem;
        }
      }
    }
    .upload {
      position: relative;
      border-radius: 0.16rem;
      // margin-top: 0.3rem;
      .wrap {
        width: 1rem;
        height: 1rem;
        position: relative;
        background-image: url('../../../assets/img/add.png');
        background-size: 100% 100%;
        border-radius: 0.16rem;
        margin-top: 0.3rem;
        input {
          position: absolute;
          width: 1rem;
          height: 1rem;
          top: 0;
          left: 0;
          opacity: 0;
          border-radius: 0.16rem;
        }
      }
      .list {
        width: 100%;
        background-color: transparent;
        display: flex;
        flex-wrap: wrap;
        img {
          width: 1rem;
          height: 1rem;
          margin-right: 0.2rem;
          margin-bottom: 0.2rem;
        }
      }
    }
    .bottom {
      margin-top: 0.24rem;
      color: #999;
      font-size: 0.24rem;
      border-top: 1px dashed #eee;
      text-align: center;
      display: flex;
      flex-direction: row-reverse;
      position: relative;
      .MP3_btn {
        position: absolute;
        // width: 0.24rem;
        // height: 0.24rem;
        left: 0.28rem;
        top: 0.15rem;
        div {
          display: flex;
          align-items: center;
          justify-content: space-between;
          height: 0.34rem;
          img {
            width: 0.24rem;
            height: 0.24rem;
            margin-right: 0.06rem;
          }
        }
      }
      // .play {
      //   background-image: url("../../../assets/img/play.png");
      //   background-size: 100% 100%;
      // }
      // .pause {
      //   background-image: url("../../../assets/img/pause.png");
      //   background-size: 100% 100%;
      // }
      .title {
        padding: 0.14rem 0;
      }
      .ops {
        display: flex;
        align-items: center;
        justify-content: center;
        color: #9c9c9c;
        font-size: 0.24rem;
        padding: 0.14rem 0.08rem 0;
        .dash {
          width: 1px;
          height: 100%;
          border-left: 1px dashed #eee;
          margin: 0 0.4rem;
        }
        div {
          display: flex;
          align-items: center;
          justify-content: space-between;
          height: 0.34rem;
          img {
            width: 0.24rem;
            height: 0.24rem;
            margin-right: 0.06rem;
          }
          .like {
            animation: like-animation 0.5s ease-in-out;
          }
          .unlike {
            animation: unlike-animation 0.5s ease-in-out;
          }
        }
      }
    }
  }
  .btns {
    margin-top: 0.24rem;
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    align-items: flex-start;
    .btn {
      width: 95%;
      border: 0.5px solid #dcdee0;
      padding: 0.12rem 0.4rem;
      padding-right: 0.4rem;
      border-radius: 0.32rem;
      font-size: 0.28rem;
      color: #222;
      text-align: left;
      margin-bottom: 0.24rem;
      position: relative;
      .next {
        position: absolute;
        width: 0.12rem;
        height: 0.26rem;
        top: 0.18rem;
        right: 0.3rem;
        background-image: url('../../../assets/img/next.png');
        background-size: 100% 100%;
      }
    }
  }

  .table {
    margin: 0.24rem 0 0.06rem 0;
    width: 5.56rem;
    overflow-x: auto;
    background: #f1f2f6;
    border-radius: 0.16rem;
    .table-style();
  }
  .toggle-expand {
    position: absolute;
    bottom: 0;
    width: 5.66rem;
    text-align: center;
    font-size: 0.24rem;
    color: #5596f2;
    height: 0.5rem;
    line-height: 0.5rem;
    margin: auto;
  }
  .table-content {
    transition: max-height 0.8s ease; /* 平滑动画效果 */
    position: relative;
    .toggle-expand-tr {
      height: 0.4rem;
      overflow: hidden;
    }
  }
  .bar-chart-wrap {
    margin: 0.24rem 0 0.06rem 0;
    width: 5.56rem;
    background: #f1f2f6;
    border-radius: 0.16rem;
    overflow-x: auto;
    height: 4.56rem;
    .chart {
      width: 5.56rem;
      height: 4.56rem;
    }
    .toggle-expand {
      position: relative;
      width: 5.66rem;
      text-align: center;
      font-size: 0.24rem;
      color: #5596f2;
      height: 0.6rem;
      line-height: 0.3rem;
      margin: auto;
    }
  }
  .line-chart-wrap {
    margin: 0.24rem 0 0.06rem 0;
    width: 5.56rem;
    overflow-x: auto;
    background: #f1f2f6;
    border-radius: 0.16rem;
    .chart {
      width: 5.56rem;
      height: 4.74rem;
    }
  }
  .pie-chart-wrap {
    margin: 0.24rem 0 0.06rem 0;
    width: 5.56rem;
    background: #f1f2f6;
    border-radius: 0.16rem;
    .chart {
      width: 5.56rem;
      height: 5.56rem;
    }
  }
  .funcs {
    display: flex;
    flex-direction: column;
    margin-top: 0.12rem;
    .suggest {
      margin-bottom: 0.16rem;
      display: flex;
      align-items: center;
      color: #bfbfbf;
      .airec,
      .toggle {
        width: 0.3rem;
        height: 0.3rem;
      }
      .airec {
        background-image: url('../../../assets/img/airec.png');
        background-size: 100% 100%;
        margin-right: 0.08rem;
      }
      .up {
        background-image: url('../../../assets/img/arrow_up.png');
        background-size: 100% 100%;
      }
      .down {
        background-image: url('../../../assets/img/arrow_down.png');
        background-size: 100% 100%;
      }
    }
    .funcs-wrap {
      display: flex;
      flex-wrap: wrap;
      width: 100%;
      background-color: #f0fafc;
      border-radius: 0.24rem;
      padding-bottom: 0.2rem;
      .func {
        width: 30%;
        padding: 0 0.2rem;
        color: #546275;
        font-size: 0.24rem;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        margin-right: 0.27rem;
        img {
          width: 0.76rem;
          height: 0.76rem;
          border-radius: 50%;
          margin-top: 0.22rem;
        }
      }
      .func:nth-child(3n) {
        margin-right: 0;
      }
    }
  }
}

.s-title {
  width: 100%;
  text-align: center;
  background: #eaf9fd;
  border-radius: 0.16rem;
  color: #899aa6;
  width: 2.8rem;
  margin: 0 auto;
  padding: 0.1rem 0;
  font-size: 0.16rem;
}

.mw:last-child {
  margin-bottom: 0;
}

@keyframes ball-triangle-path-ball-one {
  0% {
    transform: translate(0, 220%);
  }

  17% {
    opacity: 0.25;
  }

  33% {
    opacity: 1;
    transform: translate(110%, 0);
  }

  50% {
    opacity: 0.25;
  }

  66% {
    opacity: 1;
    transform: translate(220%, 220%);
  }

  83% {
    opacity: 0.25;
  }

  100% {
    opacity: 1;
    transform: translate(0, 220%);
  }
}

@keyframes ball-triangle-path-ball-two {
  0% {
    transform: translate(110%, 0);
  }

  17% {
    opacity: 0.25;
  }

  33% {
    opacity: 1;
    transform: translate(220%, 220%);
  }

  50% {
    opacity: 0.25;
  }

  66% {
    opacity: 1;
    transform: translate(0, 220%);
  }

  83% {
    opacity: 0.25;
  }

  100% {
    opacity: 1;
    transform: translate(110%, 0);
  }
}

@keyframes ball-triangle-path-ball-tree {
  0% {
    transform: translate(220%, 220%);
  }

  17% {
    opacity: 0.25;
  }

  33% {
    opacity: 1;
    transform: translate(0, 220%);
  }

  50% {
    opacity: 0.25;
  }

  66% {
    opacity: 1;
    transform: translate(110%, 0);
  }

  83% {
    opacity: 0.25;
  }

  100% {
    opacity: 1;
    transform: translate(220%, 220%);
  }
}
</style>
